Męczę się już trochę z tym problemem, a być może ktoś będzie znał rozwiązanie.
Mam model:
class Article(models.Model):
    title = models.CharField(max_length = 120, verbose_name = u'Tytuł')
    long_content = models.TextField(verbose_name = u'Treść')
    short_content = models.TextField(verbose_name = u'Krótka treść')
    category = models.ForeignKey(ArticleCategory, verbose_name = u'Kategoria')
    slug = models.SlugField(max_length = 120, unique=True, verbose_name = u'Odnośnik')
    related_articles = models.ManyToManyField("Article", verbose_name = u'Powiązane artykuły', blank = True)
Pytanie brzmi:
Jak zrobić aby artykuły były powiązane dwustronnie? To znaczy jeśli, dodam w panelu administracyjnym, że „Artykuł nr 1” jest powiązany z „Artykuł nr 2”, to jeśli wejdę na stronę edycji „Artykuł nr 2” to będę widział odpowiednie powiązanie z „Artykuł nr 1” ?
A po co tak? Rozumiem, że nie chcesz 2 razy dodawać, ale wystarczy wyfiltrować np. tak:
a1 = Article.objects.get(pk=1)lista_pk = a1.related_articles.all().values_list('id',flat=True)
lista_pk.extend( Article.objects.filter( related_articles___pk__in=[a1.id,]).values_list('id',flat=True) )
No dobra, wiem jak to pobrać 😉 Ale jak zrobić, żeby za każdym razem przy dodawaniu, aktualizowaniu, usuwaniu działało to w obie strony(na dwóch artykułach). Założenie, jest takie, że panel administracyjny będzie obsługiwać osoba, która nie będzie znała całego systemu. Kiedy zobaczy w panelu że jest zaznaczony powiązany artykuł no to super, ale jeśli przejdzie do tego powiązanego artykułu w panelu to może zobaczyć, że nie jest on powiązany w drugą stronę. Chciałbym uniknąć takich niejasności 😉 No chyba, że można to jakoś od strony panelu załatwić ?
Mam nadzieję, że nie zakręciłem 😛
proszę bardzo, mam nadzieję że o to chodziło:
w models.py wklejasz
(coś markdown nie działa 🙂 )
from django.db.models import signals
def m2m(sender, instance, action, reverse, model, pk_set, **kwargs):
–if action == „post_add”:
—-for i in Article.objects.filter( pk__in=pk_set).exclude( related_articles__pk__in=[ instance.id, ] ):
——i.related_articles.add( instance )
–if action in [ „post_remove”,”post_clear”,]:
—-for i in Article.objects.filter( pk__in=pk_set, related_articles__pk__in=[ instance.id, ] ):
——i.related_articles.remove( instance )
signals.m2mchanged.connect( m2m,sender=Article.relatedarticles.through )
`
wynik z schella:
„
zobacz to – ale zgodnie z tym co piszą w dokumentacji, relacja m2m z 'self’ powinna być symetryczna
Sprawdziłem jeszcze przed chwilą na prostym modelu i relacja m2m z 'self’ jest symetryczna, czyli zachowuje się właśnie tak jak chcesz – zachowanie to można wyłączyć za pomocą argumentu symmetrical=False
@mrk: dzięki 🙂 dokładnie o to mi chodziło 🙂
dziwię się tylko dlaczego Ci to nie działało – m2m jest domyślnie symetryczna jeżeli model jest w relacji ze sobą
Nie działało ponieważ było models.ManyToManyField(„Article”) a nie models.ManyToManyField(„self”). Sam się na to nadziałem 🙂 Czasem warto doczytać dokumentację 🙂